﻿
--------------------------------------------
-- 函式引用及變數宣告
--------------------------------------------
NextWall = LibStub("AceAddon-3.0"):NewAddon("NextWall", "AceConsole-3.0","AceEvent-3.0","AceTimer-3.0")

 
local L = LibStub("AceLocale-3.0"):GetLocale("NextWall", true)
local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LDB and LibStub("LibDBIcon-1.0", true)
local self = NextWall

local NW_SoR = {}


local function debug(msg)
	if NextWall.db.profile.debug then
		DEFAULT_CHAT_FRAME:AddMessage("nwDebug: "..msg)
	end
end


local ClassColor = {
	DEATHKNIGHT = "C41F3B",
	DRUID = "FF7D0A",
	HUNTER = "ABD473",
	MAGE = "69CCF0",
	PALADIN = "F58CBA",
	PRIEST = "FFFFFF",
	ROGUE = "FFF569",
	SHAMAN = "2459FF",
	WARLOCK = "9482C9",
	WARRIOR = "C79C6E",
}

local db
local defaults = {
	profile = {
		disabled = true,
		alertdied = false,
		channel = {
			solo = "C",
			party = "E",
			raid = "F",
			raidleader = "F",
		},
		minimap = {
			hide = false,
			minimapPos = 250,
			radius = 80,
		},
	}
}

defaults.profile.skill = {
	-- 自開盾牆
	[48792]=	{["type"]=1,["order"]=1,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.DEATHKNIGHT,}, -- 冰錮堅韌
	[55233]=	{["type"]=1,["order"]=2,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.DEATHKNIGHT,}, -- 血族之裔
	[51271]=	{["type"]=1,["order"]=3,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.DEATHKNIGHT,}, -- 無毀堅甲
	[871]=	{["type"]=1,["order"]=4,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.WARRIOR,}, -- 盾牆
	[12975]=	{["type"]=1,["order"]=5,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.WARRIOR,}, -- 破釜沉舟
	[2565]=	{["type"]=1,["order"]=6,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.WARRIOR,}, -- 盾牌格擋
	[22812]=	{["type"]=1,["order"]=7,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.DRUID,}, -- 樹皮術
	[61336]=	{["type"]=1,["order"]=8,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.DRUID,}, -- 求生本能
	[498]=	{["type"]=1,["order"]=9,["countnum"]={1,2},["duration"]=nil,["color"]=ClassColor.PALADIN,}, -- 聖佑術
	-- 減傷增益
	[33206]=	{["type"]=2,["order"]=10,["countnum"]={1,2},["duration"]=8 ,["color"]=ClassColor.PRIEST,},--  痛苦鎮壓
	[47788]=	{["type"]=2,["order"]=11,["countnum"]={1,2},["duration"]=12,["color"]=ClassColor.PRIEST,},--  守護聖靈
	[6940]=	{["type"]=2,["order"]=12,["countnum"]={1,2},["duration"]=12,["color"]=ClassColor.PALADIN,},--  犧牲聖禦
	[10278]=	{["type"]=2,["order"]=13,["countnum"]={1,2,3,4},["duration"]=10,["color"]=ClassColor.PALADIN,},--  保護聖禦
	-- 神性犧牲
	[64205]=	{["type"]=3,["order"]=14,["countnum"]={1,2},["duration"]=10,["color"]=ClassColor.PALADIN,},--  神性犧牲
	[70940]=	{["type"]=3,["order"]=15,["countnum"]={1,2},["duration"]=6,["color"]=ClassColor.PALADIN,},--  神性犧牲
	-- debuff類
	[66233]=	{["type"]=4,["order"]=16,["countnum"]=nil,["duration"]=nil,["color"]=ClassColor.PALADIN,},--  忠防Debuff
	-- 誤導類
	[57934]=	{["type"]=5,["order"]=19,["countnum"]={1,2},["duration"]=30,["color"]=ClassColor.ROGUE,},--  偷天
	[34477]=	{["type"]=5,["order"]=20,["countnum"]={1,2},["duration"]=30,["color"]=ClassColor.HUNTER,},--  誤導
	
}

for k,v in pairs(defaults.profile.skill) do
		v["disabled"] = true
		v["countdown"] = false
		v["removed"] = false
		if v["type"] == 1 then
			v["appliedalert"] 	= "%6s ++ %n - %ds"
			v["countdownalert"] 	= "%6s -- %n - %ds"
			v["removealert"] 		= "%6s -- %n - "..L["REMOVED"]
		elseif v["type"] == 2 then
			v["appliedalert"] 	= "%6t ++ %n(%6s) - %ds"
			v["countdownalert"] 	= "%6t -- %n(%6s) - %ds"
			v["removealert"] 		= "%6t -- %n(%6s) - "..L["REMOVED"]
		elseif v["type"] == 3 then
			v["appliedalert"] 	= "%6s ++ %n - %ds"
			v["countdownalert"] 	= "%6s -- %n - %ds"
			v["removealert"] 		= "%6s -- %n - "..L["REMOVED"]
		elseif v["type"] == 4 then
			v["appliedalert"] 	= "%6s ++ %n - %ds"
			v["countdownalert"] 	= "%6s -- %n - %ds"
			v["removealert"] 		= "%6s -- %n - "..L["REMOVED"]
		elseif v["type"] == 5 then
			v["appliedalert"] 	= "%6t ++ %n(%6s)"
			v["countdownalert"] 	= "%6t -- %n(%6s)"
			v["removealert"] 		= "%6t -- %n(%6s)"
		end
		v.channel = {
			solo = "C",
			party = "E",
			raid = "F",
			raidleader = "F",
		}
end


--------------------------------------------
-- 初始化、切換、開關
--------------------------------------------
function NextWall:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("NextWallDB", defaults, "Default")
	db = self.db.profile
	if not db.version then
		if not db.minimap then
			db.minimap = {
				hide = false,
				minimapPos = 250,
				radius = 80,
			}
		end
		db.version = 1
	end

	-- LDB launcher

	if LDB then
		NextWallDS = LDB:NewDataObject("NextWall", {
			icon = "Interface\\AddOns\\NextWall\\NextWall_enable.tga",

			label = "NextWall",
			text = "NextWall",
			type = "data source",
			OnClick = function(self, button)
				if button == "RightButton" then
					NextWall:ConfigMenu()
				end
		
				if button == "LeftButton" then
					NextWall:Toggle()
				end
			end,
			OnTooltipShow = function(tooltip)
				tooltip:AddLine("NextWall")
				tooltip:AddLine(" ")
				tooltip:AddLine(L["Click to toggle NextWall"])
				tooltip:AddLine(L["Right-click to open the options menu"])
			end
		})
		if LDBIcon then
			LDBIcon:Register("NextWall", NextWallDS, db.minimap)
			if (not db.minimap.hide) then LDBIcon:Show("NextWall") end
		end
	end

	self:SetupOptions()
	
	self:RegisterChatCommand("nextwall", NextWall.ConfigMenu )
	self:RegisterChatCommand("nw", NextWall.ConfigMenu )
	self:RegisterChatCommand("rl", function() ReloadUI() end)

end

function NextWall:Toggle()
	NextWall.db.profile.disabled = not NextWall.db.profile.disabled
	if NextWall.db.profile.disabled then
		DEFAULT_CHAT_FRAME:AddMessage(L["NextWall Disabled."])
		NextWall:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
		NextWallDS.icon = "Interface\\AddOns\\NextWall\\NextWall_disable.tga"
		NextWall:ClearAllTimer()
	else
		DEFAULT_CHAT_FRAME:AddMessage(L["NextWall Enabled."])
		NextWall:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
		NextWall:PARTY_MEMBERS_CHANGED()
		NextWallDS.icon = "Interface\\AddOns\\NextWall\\NextWall_enable.tga"
	end
end

function NextWall:OnEnable()
	DEFAULT_CHAT_FRAME:AddMessage(L["NextWall Loaded."])
	NextWall:RegisterEvent("PARTY_MEMBERS_CHANGED")
	NextWall:RegisterEvent("CHANNEL_UI_UPDATE")
	if NextWall.db.profile.disabled then
		NextWallDS.icon = "Interface\\AddOns\\NextWall\\NextWall_disable.tga"
	else
		NextWall:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
		NextWall:PARTY_MEMBERS_CHANGED()
		NextWallDS.icon = "Interface\\AddOns\\NextWall\\NextWall_enable.tga"
	end
end

function NextWall:OnDisable()
 	NextWall:UnregisterEvent("PARTY_MEMBERS_CHANGED")
	NextWall:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	NextWall:UnregisterEvent("CHANNEL_UI_UPDATE")
end

function NextWall:ConfigMenu()
	InterfaceOptionsFrame_OpenToCategory(NextWall.optionsFrames.Profiles)
	InterfaceOptionsFrame_OpenToCategory(NextWall.optionsFrames.NextWall)
end

--------------------------------------------
-- 各種事件處理
--------------------------------------------
function NextWall:CHANNEL_UI_UPDATE()
	NextWall.GenerateOptions()
	LibStub("AceConfigRegistry-3.0"):NotifyChange("NextWall")
end

function NextWall:PARTY_MEMBERS_CHANGED()
	NW_RaidList = {}
	if GetNumRaidMembers() > 0 then 
		for i=1,GetNumRaidMembers() do
			NW_RaidList[UnitGUID("raid"..i)] = "raid"..i
		end
	end
	if GetNumPartyMembers() > 0 then
		for i=1,GetNumPartyMembers() do
			NW_RaidList[UnitGUID("party"..i)]="party"..i
		end
	end
	NW_RaidList[UnitGUID("player")] = "player"
end

function NextWall:COMBAT_LOG_EVENT_UNFILTERED(_, timeFlag, event, sGUID, sName, sFlags, dGUID, dName, dFlags, spellID, spellName, dddd, secSpellId)
	local sUnitID,dUnitID = NW_RaidList[sGUID],NW_RaidList[dGUID]

	if event == "UNIT_DIED" and dUnitID and NextWall.db.profile.alertdied and UnitHealth(dUnitID) < 1 then
		if NW_SoR[dName] then
			debug(dName .." 的天使 ".. L[" Died."])
			NW_SoR[dName] = nil
		else
			local k = {[1]=1,[2]=2,[4]=3,[8]=4,[16]=5,[32]=6,[64]=7,[128]=8}
			local mark = k[mod(floor(dFlags/16^5),256)] or 0
			if mark and mark > 0 then
				GroupSay("{rt"..mark.."}" .. dName .. L[" Died."])
				debug(dName .. L[" Died."].." ; rt="..mark)
			else
				GroupSay( dName .. L[" Died."])
				debug(dName .. L[" Died."])
			end
		end
	end

	if event == "SPELL_AURA_APPLIED" and spellID == 27827 then
		debug(sName.." aura applied:27827")
		NW_SoR[sName] = 1
		NextWall:ScheduleTimer(function(s) NW_SoR[s] = nil end,16,sName)
	end
	
	if spellID == 12976 then spellID = 12975 end -- 都是破釜
	if not NextWall.db.profile.skill[spellID] then return end
	local cursk = NextWall.db.profile.skill[spellID]
	if cursk.disabled then return end


	if not sUnitID or not dUnitID then return end
	if event == "SPELL_AURA_APPLIED" then
		local expi = NextWall:GetAuraExpiration(dUnitID, spellName) or NextWall:GetAuraExpiration(dUnitID, spellName,"HARMFUL") or cursk.duration
		if ( cursk.type == 2 or cursk.type == 4 ) then  -- debuff類 / 減傷增益
			local alertmsg = NextWall:AlertReplace(cursk.appliedalert,sName,dName,spellName,expi)
			GroupSay(alertmsg, spellID)
			if cursk.countdown then
				NextWall:RegistTimer(dName, spellID, spellName, sName, expi, cursk.countnum)
			end
		elseif ( cursk.type == 1 or cursk.type == 3 ) and sUnitID == dUnitID then  -- 神性犧牲
			local alertmsg = NextWall:AlertReplace(cursk.appliedalert,sName,dName,spellName,expi)
			GroupSay(alertmsg, spellID)
			if cursk.countdown then
				NextWall:RegistTimer(dName, spellID, spellName, sName, expi, cursk.countnum)
			end
		end
	elseif event == "SPELL_CAST_SUCCESS" and sUnitID ~= dUnitID and cursk.type == 5 then  -- 施法成功
			local alertmsg = NextWall:AlertReplace(cursk.appliedalert,sName,dName,spellName,expi)
			GroupSay(alertmsg, spellID)
	elseif event == "SPELL_AURA_REMOVED" and dUnitID and cursk.type ~= 5 and ( cursk.type ~= 3 or sName == dName ) then  -- 效果消失
		if cursk.removed then
			local alertmsg = NextWall:AlertReplace(cursk.removealert,sName,dName,spellName)
			GroupSay(alertmsg, spellID)
		end
		NextWall:ClearTimer(dName,spellName)
	end
end

--------------------------------------------
-- 計時器陣列功能
--------------------------------------------
function NextWall:ClearAllTimer()
	if not NW_TimerTtable then return end
	for k1,d1 in pairs(NW_TimerTtable) do
		for k2,v2 in pairs(v1) do
			for k3,v3 in pairs(v2) do
				NextWall:CancelTimer(v3,1)
			end
		end
	end
	NW_TimerTtable = {}
end

function NextWall:ClearTimer(dName,spellName)
	if not NW_TimerTtable or not dName or not spellName or not NW_TimerTtable[dName] or not NW_TimerTtable[dName][spellName] then return end
	for k1,v1 in pairs(NW_TimerTtable[dName][spellName]) do
		NextWall:CancelTimer(v1,1)
	end
end

function NextWall:RegistTimer(dName, spellID, spellName, sName, expi, countnum)
	if not dName or not spellID or not spellName or not sName or not expi then return end
	NextWall:ClearTimer(dName,spellName)
	NW_TimerTtable = NW_TimerTtable or {}
	NW_TimerTtable[dName] = NW_TimerTtable[dName] or {}
	NW_TimerTtable[dName][spellName] = NW_TimerTtable[dName][spellName] or {}
	NW_TimerTtable[dName][spellName][sName] = NW_TimerTtable[dName][spellName][sName] or {}
	countnum = countnum or {1,2}

	for i = 1,getn(countnum) do
		if expi > countnum[i] then
			local delaytime = expi - countnum[i] - select(3,GetNetStats())/1000
			local alertmsg = NextWall:AlertReplace(NextWall.db.profile.skill[spellID].countdownalert, sName, dName, spellName, countnum[i])
			local timer = NextWall:ScheduleTimer(GroupSay, delaytime, {alertmsg,spellName})
			NW_TimerTtable[dName][spellName][sName] = timer
		end
	end
end

--------------------------------------------
-- 其他功能
--------------------------------------------
function NextWall:AlertReplace(des,s,t,n,d)  -- 述句,施法者,被施法者,法術,時間
	if s then 
		local _,_,len_s = strfind(des,'%%(%d*)s')
		des = string.gsub(des,'%%(%d*)s',string.sub(s,1,tonumber(len_s)))
	end
	if t then 
		local _,_,len_t = strfind(des,'%%(%d*)t')
		des = string.gsub(des,'%%(%d*)t',string.sub(t,1,tonumber(len_t)))
	end
	if n then 
		local _,_,len_n = strfind(des,'%%(%d*)n')
		des = string.gsub(des,'%%(%d*)n',string.sub(n,1,tonumber(len_n)))
	end
	if d then
		des = string.gsub(des,'%%(%d*)d',d)
	end
	return des
end

function NextWall:GetAuraExpiration(unit, aura, filter)
	if unit and aura then 
		local buff,_,_,_,_,duration,expirationTime = UnitAura(unit,aura,nil,filter) 
		if duration == 0 or not expirationTime then return nil end
		return duration
	end
end

function GroupSay(arg,id)
	if type(arg) == "table" then
		arg	= arg[1] 
		id 	= arg[2]
	end
	if not arg then return end


	local maptable = {['A'] = 'NULL', ['B'] = 'EMOTE', ['C'] = 'SAY', ['D'] = 'YELL', ['E'] = 'PARTY', ['F'] = 'RAID', ['G'] = 'RAID_WARNING',}
	
	local channel
	local char
	local default
	
	if not id then
		default = NextWall.db.profile.channel
		char = default
	else
		char = NextWall.db.profile.skill[id].channel
		default = NextWall.db.profile.channel
	end
	
	
	if GetNumRaidMembers() > 0 then
		if IsRaidOfficer() or IsRaidLeader() then
			channel = maptable[char.raidleader] or char.raidleader	or maptable[default.raidleader] or default.raidleader
		else
			channel = maptable[char.raid] 		or char.raid		or maptable[default.raid] or default.raid
		end
	elseif GetNumPartyMembers() > 0 then
			channel = maptable[char.party] 		or char.party		or maptable[default.party] or default.party
	else
			channel = maptable[char.solo] 		or char.solo		or maptable[default.solo] or default.solo
	end
	if channel and channel ~= "NULL" then
		if tonumber(channel) then
			SendChatMessage(arg , "CHANNEL", nil, channel)
		else
			SendChatMessage(arg,channel)
		end
	end
end

function NextWall:TableToString(Table)
	if type(Table) ~= "table" then return end
	local String = ""
	for k,v in pairs(Table) do
		String = String .. v .. ","
	end
	return String:sub(1,String:len()-1)
end

function NextWall:StringToTable(String)
	if type(String) ~= "string" then return end
	String = string.replace(String," ","")
	local Table = {}
	string.gsub(String, "(%d+)", function(a) tinsert(Table,tonumber(a))  end)
	return Table
end

do
    local chanTable = {}
    local function buildChanTable(t, num, name, ...)
		if name and num then
			if name ~= L["LOCALDEF"] and name ~= L["WORLDDEF"] and name ~= L["GUILDREC"] and name ~= _G.GENERAL and name ~= _G.TRADE and name ~= _G.LOOKING_FOR_GROUP then
				num =tostring(num)
				t[num] = L["Priv:"]..name
			end
			return buildChanTable(t, ...)
		end
        return t
    end
    function GetPrivChannelTable(t)
        if not t then 
            t = chanTable 
        end
        buildChanTable(t, _G.GetChannelList())
        return t 
    end
end
--------------------------------------------
-- 設定選單
--------------------------------------------
function NextWall:SetupOptions()
	LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("NextWall", self.GenerateOptions)

	local ACD3 = LibStub("AceConfigDialog-3.0")
	NextWall.optionsFrames = {}
	NextWall.optionsFrames.NextWall		= ACD3:AddToBlizOptions("NextWall", "NextWall",nil, "general")
	NextWall.optionsFrames.Skill		= ACD3:AddToBlizOptions("NextWall", L["Skills"],"NextWall", "skills")
	NextWall.optionsFrames.Profiles		= ACD3:AddToBlizOptions("NextWall", L["Profiles"], "NextWall","profiles")
end

function NextWall.GenerateOptions()
	if NextWall.noconfig then assert(false, NextWall.noconfig) end
	--if not NextWall.options then
		NextWall.GenerateOptionsInternal()
	--	NextWall.GenerateOptionsInternal = nil
	--end
	return NextWall.options
end

function NextWall.GenerateOptionsInternal()
	local toggle = {
		order = 1,
		type = "toggle",
		name = L["Enable NextWall"],
		desc = L["Enable NextWall to alert the damage reduction duration."],
		get = function() return not NextWall.db.profile.disabled end,
		set = function(info, v) NextWall:Toggle() end,
	}
	local alertdied = {
		order = 2,
		type = "toggle",
		name = L["Alert Died"],
		desc = L["Alert when member die."],
		get = function() return NextWall.db.profile.alertdied end,
		set = function(info, v) NextWall.db.profile.alertdied = v 
			if v then 
				DEFAULT_CHAT_FRAME:AddMessage(L["Alert Died"]..L[" Alert Enabled."])
			else
				DEFAULT_CHAT_FRAME:AddMessage(L["Alert Died"]..L[" Alert Disabled."])
			end
		end,
	}
	local minimap = {
		type = "toggle",
		name = L["Show minimap icon"],
		desc = L["Toggle showing or hiding the minimap icon."],
		get = function() return not NextWall.db.profile.minimap.hide end,
		set = function(info, v)
			NextWall.db.profile.minimap.hide = not v
			if v then
				LDBIcon:Show("NextWall")
			else
				LDBIcon:Hide("NextWall")
			end
		end,
		order = 3,
		hidden = function() return not LDBIcon or not LDBIcon:IsRegistered("NextWall") end,
	}
	local debugmode = {
		type = "toggle",
		name = L["Debug"],
		desc = L["Toggle Debug Mode."],
		get = function() return NextWall.db.profile.debug end,
		set = function(info, v)	NextWall.db.profile.debug = v
			if v then 
				DEFAULT_CHAT_FRAME:AddMessage(L["Debug"]..L[" Alert Enabled."])
			else
				DEFAULT_CHAT_FRAME:AddMessage(L["Debug"]..L[" Alert Disabled."])
			end
		end,
		order = 4,
		hidden = function() return not LDBIcon or not LDBIcon:IsRegistered("NextWall") end,
	}
	local solo = {
		name = L['When Solo'],
		desc = L['When Solo.'],
		type = 'select',
		order = 1,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
		}),
		get = function(info) NextWall.db.profile.channel = NextWall.db.profile.channel or {} return NextWall.db.profile.channel.solo or "" end,
		set = function(info, value) NextWall.db.profile.channel.solo = value end
	}
	local party = {
		name = L['When in Party'],
		desc = L['When in Party.'],
		type = 'select',
		order = 2,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
			['E'] = L['PARTY'],
			['G'] = L['RAID_WARNING'],
		}),
		get = function(info) NextWall.db.profile.channel = NextWall.db.profile.channel or {} return NextWall.db.profile.channel.party or "" end,
		set = function(info, value) NextWall.db.profile.channel.party = value end
	}
	local raid = {
		name = L['When in a Raid'],
		desc = L['When in a Raid.'],
		type = 'select',
		order = 3,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
			['E'] = L['PARTY'],
			['F'] = L['RAID'],
		}),
		get = function(info) NextWall.db.profile.channel = NextWall.db.profile.channel or {} return NextWall.db.profile.channel.raid or "" end,
		set = function(info, value) NextWall.db.profile.channel.raid = value end
	}
	local raidleader = {
		name = L['RaidLeader or Assistant'],
		desc = L['When in a Raid and you are RaidLeader or Assistant.'],
		type = 'select',
		order = 4,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
			['E'] = L['PARTY'],
			['F'] = L['RAID'],
			['G'] = L['RAID_WARNING'],
		}),
		get = function(info) NextWall.db.profile.channel = NextWall.db.profile.channel or {} return NextWall.db.profile.channel.raidleader or "" end,
		set = function(info, value) NextWall.db.profile.channel.raidleader = value end
	}
	NextWall.options = {
		name = 'NextWall',
		type = "group",
		args = {
			general = {
				name = 'NextWall',
				type = "group",
				args = {
					toggle = toggle,
					alertdied = alertdied,
					minimap = minimap,
					debugmode = debugmode,
					output = {
						order = 3,
						type = "group",
						name = L["Output Channel"],
						desc = L["Select output channel."],
						args = {
							solo = solo,
							party = party,
							raid = raid,
							raidleader = raidleader,
						},
					},
				},
			},
			skills = {
				name = 'NextWall',
				type = "group",
				args = NextWall:Skillmenu(),
			},
		},
	}
	NextWall.options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(NextWall.db)
end

function NextWall:Skillmenu() -- for sort
	local arg = {}
	for k,v in pairs(NextWall.db.profile.skill) do
		arg[tostring(k)] = NextWall:SkillOption(k,v.order)
	end
	return arg
end

function NextWall:SkillOption(id,ord)
	local solo = {
		name = L['When Solo'],
		desc = L['When Solo.'],
		type = 'select',
		order = 14,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
		}),
		get = function(info) NextWall.db.profile.skill[id].channel = NextWall.db.profile.skill[id].channel or {} return NextWall.db.profile.skill[id].channel.solo or "" end,
		set = function(info, value) NextWall.db.profile.skill[id].channel.solo = value end
	}
	local party = {
		name = L['When in Party'],
		desc = L['When in Party.'],
		type = 'select',
		order = 15,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
			['E'] = L['PARTY'],
			['G'] = L['RAID_WARNING'],
		}),
		get = function(info) NextWall.db.profile.skill[id].channel = NextWall.db.profile.skill[id].channel or {} return NextWall.db.profile.skill[id].channel.party or "" end,
		set = function(info, value) NextWall.db.profile.skill[id].channel.party = value end
	}
	local raid = {
		name = L['When in a Raid'],
		desc = L['When in a Raid.'],
		type = 'select',
		order = 16,
		values = GetPrivChannelTable({
			['A'] = L["NULL"],
			['B'] = L['EMOTE'],
			['C'] = L['SAY'],
			['D'] = L['YELL'],
			['E'] = L['PARTY'],
			['F'] = L['RAID'],
		}),
		get = function(info) NextWall.db.profile.skill[id].channel = NextWall.db.profile.skill[id].channel or {} return NextWall.db.profile.skill[id].channel.raid or "" end,
		set = function(info, value) NextWall.db.profile.skill[id].channel.raid = value end
	}
	local raidleader = {
			name = L['RaidLeader or Assistant'],
			desc = L['When in a Raid and you are RaidLeader or Assistant.'],
			type = 'select',
			order = 17,
			values = GetPrivChannelTable({
				['A'] = L["NULL"],
				['B'] = L['EMOTE'],
				['C'] = L['SAY'],
				['D'] = L['YELL'],
				['E'] = L['PARTY'],
				['F'] = L['RAID'],
				['G'] = L['RAID_WARNING'],
			}),
		get = function(info) NextWall.db.profile.skill[id].channel = NextWall.db.profile.skill[id].channel or {} return NextWall.db.profile.skill[id].channel.raidleader or "" end,
		set = function(info, value) NextWall.db.profile.skill[id].channel.raidleader = value end
		}

	return {
		type = "group",
		order=ord,
		name = string.gsub("|cff"..defaults.profile.skill[id].color..GetSpellInfo(id).."|r","\124\124","\124"),
		args = {
			enable = {
				type = "toggle",
				name = L["Enable"],
				desc = L["Toggle to alert this aura."],
				get = function() 
					NextWall.db.profile.skill = NextWall.db.profile.skill or {} 
					NextWall.db.profile.skill[id] = NextWall.db.profile.skill[id] or {} 
					return not NextWall.db.profile.skill[id].disabled
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].disabled = not v
					if v then
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Enabled."])
					else
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Disabled."])
					end
				end,
				order = 1,
			},
			removed = {
				type = "toggle",
				name = L["Aura Removed"],
				desc = L["Toggle to alert this aura removed."],
				get = function() 
					NextWall.db.profile.skill = NextWall.db.profile.skill or {} 
					NextWall.db.profile.skill[id] = NextWall.db.profile.skill[id] or {} 
					return NextWall.db.profile.skill[id].removed
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].removed = v
					if v then
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Removed Enabled."])
					else
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Removed Disabled."])
					end
				end,
				order = 3,
			},
			countdown = {
				type = "toggle",
				name = L["Countdown"],
				desc = L["Toggle Countdown."],
				get = function() 
					return NextWall.db.profile.skill[id].countdown
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].countdown = v
					if v then
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Countdown Enabled."])
					else
						DEFAULT_CHAT_FRAME:AddMessage(GetSpellLink(id)..L[" Alert Countdown Disabled."])
					end
				end,
				order = 2,
			},
			blank = {
				order = 4,
				type = "description",
				name = " ",
			},
			solo = solo,
			party = party,
			raid = raid,
			raidleader = raidleader,
			alert1 = {
				type = "input",
				name = L["Alert"],
				desc = L["Alert description."],
				get = function() 
					return NextWall.db.profile.skill[id].appliedalert
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].appliedalert = v
				end,
				order = 8,
			},
			alert2 = {
				type = "input",
				name = L["Removed"],
				desc = L["Removed description."],
				get = function() 
					return NextWall.db.profile.skill[id].removealert
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].removealert = v
				end,
				order = 9,
			},
			alert3 = {
				type = "input",
				name = L["Countdown"],
				desc = L["Countdown description."],
				get = function() 
					return NextWall.db.profile.skill[id].countdownalert
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].countdownalert = v
				end,
				order = 10,
			},
			alert3sec = {
				type = "input",
				name = L["Countdown Times"],
				desc = L["Countdown Times."],
				get = function() 
					return NextWall:TableToString(NextWall.db.profile.skill[id].countnum)
				end,
				set = function(info, v)
					NextWall.db.profile.skill[id].countnum = NextWall:StringToTable(v)
				end,
				order = 11,
			},
			intro = {
				order = 12,
				type = "description",
				name = L["Description Usage."],
			},
		}
	}
end




